import React, { useState, useRef, useEffect } from 'react';
import { Button } from "./ui/button";
import { Textarea } from "./ui/textarea";
import { useLanguage } from "~/lib/LanguageContext";
import { 
  PaperAirplaneIcon, 
  PaperClipIcon, 
  ClipboardIcon, 
  PlusIcon,
  TrashIcon,
  PencilIcon,
  CheckIcon,
  XMarkIcon
} from '@heroicons/react/24/outline';
import MarkdownViewer from './markdown-viewer';
import useChatSessions, { Message, ChatSession } from '~/hooks/useChatSessions';

interface AIChatStreamProps {
  repoUrl?: string;
  selectedCode?: string;
  selectedDocument?: string;
  documentId?: string;
  codeId?: string;
  onClose?: () => void;
}

export default function AIChatStream({ 
  repoUrl, 
  selectedCode,
  selectedDocument,
  documentId,
  codeId,
  onClose 
}: AIChatStreamProps) {
  const { t } = useLanguage();
  const [input, setInput] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState('');
  const [showSessionList, setShowSessionList] = useState(false);
  const [editingSessionId, setEditingSessionId] = useState<string | null>(null);
  const [editSessionTitle, setEditSessionTitle] = useState('');
  const [clipboardContent, setClipboardContent] = useState<string>('');
  const [streamingContent, setStreamingContent] = useState('');
  const messagesEndRef = useRef<HTMLDivElement>(null);
  
  // 使用聊天会话Hook
  const { 
    sessions, 
    activeSessionId, 
    createSession, 
    getActiveSession, 
    updateSessionMessages, 
    deleteSession,
    setActiveSession,
    renameSession
  } = useChatSessions({ 
    repoUrl, 
    documentId, 
    codeId 
  });
  
  // 获取当前激活的会话
  const activeSession = getActiveSession();
  
  // 使用localStorage获取当前选择的模型和API密钥
  const getModelAndApiKey = () => {
    if (typeof window === 'undefined') return { model: 'openai-o3', apiKey: '' };
    
    const model = localStorage.getItem('selected_model') || 'openai-o3';
    const apiKey = localStorage.getItem('api_key') || '';
    
    return { model, apiKey };
  };
  
  // 初始化聊天，添加系统消息
  useEffect(() => {
    // 只有在有仓库URL或其他上下文时才创建聊天
    if (!repoUrl && !selectedCode && !selectedDocument) {
      return;
    }
    
    // 如果没有活动会话，创建一个新会话
    if (!activeSession) {
      const systemMessage: Message = {
        role: 'system',
        content: `你是GitDiagram项目的AI助手。只回答与以下GitHub仓库相关的问题: ${repoUrl || '未指定'}。
        如果问题与此仓库无关，请礼貌拒绝回答。${selectedCode ? '用户已选择代码片段进行分析。' : ''}${selectedDocument ? '用户已选择文档内容进行解释。' : ''}`
      };
      
      createSession(systemMessage);
    }
  }, [repoUrl, selectedCode, selectedDocument, activeSession]);
  
  // 滚动到最新消息
  useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [activeSession?.messages, streamingContent]);
  
  // 访问用户剪贴板
  const readFromClipboard = async () => {
    try {
      const text = await navigator.clipboard.readText();
      setClipboardContent(text);
      return text;
    } catch (err) {
      console.error('Failed to read clipboard:', err);
      setError('无法访问剪贴板。请确保您授予了剪贴板访问权限。');
      return '';
    }
  };

  // 流式发送消息到指定的AI模型
  const sendMessage = async () => {
    if (!input.trim() && !clipboardContent) return;
    if (!activeSession) return;
    
    // 获取当前模型和API密钥
    const { model, apiKey } = getModelAndApiKey();
    if (!apiKey) {
      setError('请先设置API密钥');
      return;
    }
    
    const messageContent = clipboardContent 
      ? `${input.trim()}\n\n代码/文本：\n\`\`\`\n${clipboardContent}\n\`\`\``
      : input;
    
    const userMessage: Message = {
      role: 'user',
      content: messageContent
    };
    
    // 添加用户消息到当前会话
    const newMessages = [...activeSession.messages, userMessage];
    updateSessionMessages(activeSession.id, newMessages);
    
    // 重置输入和剪贴板
    setInput('');
    setClipboardContent('');
    setStreamingContent('');
    setIsLoading(true);
    setError('');
    
    try {
      const baseUrl = process.env.NEXT_PUBLIC_API_DEV_URL ?? "https://api.codemariner.com";
      
      // 根据模型选择不同的流式API端点
      const endpoint = model === 'deepseek' 
        ? `${baseUrl}/deepseek/chat/stream` 
        : `${baseUrl}/openai/chat/stream`;
      
      // 创建请求
      const response = await fetch(endpoint, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          messages: newMessages.map(msg => ({
            role: msg.role,
            content: msg.content
          })),
          api_key: apiKey,
          model: model,
          repository_url: repoUrl || '',
          code: selectedCode || '',
          document: selectedDocument || ''
        }),
      });
      
      if (!response.ok) {
        throw new Error(`错误: ${response.status}`);
      }
      
      // 处理流式响应
      const reader = response.body?.getReader();
      if (!reader) throw new Error('无法获取响应流');
      
      // 累计接收到的内容
      let receivedContent = '';
      
      // 设置解码器
      const decoder = new TextDecoder();
      
      // 读取流
      while (true) {
        const { done, value } = await reader.read();
        
        // 如果流结束，退出循环
        if (done) {
          break;
        }
        
        // 解码接收到的数据
        const chunk = decoder.decode(value, { stream: true });
        
        // 添加到累计内容
        receivedContent += chunk;
        
        // 更新展示的流式内容
        setStreamingContent(receivedContent);
      }
      
      // 流结束后，将完整内容作为助手消息添加到会话
      const assistantMessage: Message = {
        role: 'assistant',
        content: receivedContent || '抱歉，我无法生成回复。'
      };
      
      // 更新会话消息
      const updatedMessages = [...newMessages, assistantMessage];
      updateSessionMessages(activeSession.id, updatedMessages);
      
      // 清除流式内容
      setStreamingContent('');
      
    } catch (err) {
      console.error('发送消息时出错:', err);
      setError(err instanceof Error ? err.message : '发送消息时出错');
      
      // 如果出错，仍将错误信息作为助手消息添加到会话，以保留对话历史
      const errorMessage: Message = {
        role: 'assistant',
        content: `错误: ${err instanceof Error ? err.message : '发送消息时出错'}`
      };
      
      const updatedMessages = [...newMessages, errorMessage];
      updateSessionMessages(activeSession.id, updatedMessages);
    } finally {
      setIsLoading(false);
    }
  };
  
  // 处理输入和发送
  const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
    setInput(e.target.value);
  };
  
  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      sendMessage();
    }
  };
  
  // 创建新的聊天会话
  const handleNewSession = () => {
    const systemMessage: Message = {
      role: 'system',
      content: `你是GitDiagram项目的AI助手。只回答与以下GitHub仓库相关的问题: ${repoUrl || '未指定'}。
      如果问题与此仓库无关，请礼貌拒绝回答。${selectedCode ? '用户已选择代码片段进行分析。' : ''}${selectedDocument ? '用户已选择文档内容进行解释。' : ''}`
    };
    
    createSession(systemMessage);
    setShowSessionList(false);
  };
  
  // 处理会话列表显示
  const toggleSessionList = () => {
    setShowSessionList(!showSessionList);
  };
  
  // 开始编辑会话标题
  const startEditingSession = (sessionId: string, currentTitle: string) => {
    setEditingSessionId(sessionId);
    setEditSessionTitle(currentTitle);
  };
  
  // 保存会话标题
  const saveSessionTitle = (sessionId: string) => {
    if (editSessionTitle.trim()) {
      renameSession(sessionId, editSessionTitle.trim());
    }
    setEditingSessionId(null);
  };
  
  // 取消编辑会话标题
  const cancelEditingSession = () => {
    setEditingSessionId(null);
  };
  
  return (
    <div className="flex flex-col h-full border-2 border-gray-200 rounded-lg bg-white dark:bg-gray-900 dark:border-gray-700 shadow-lg">
      <div className="flex justify-between items-center border-b p-3 dark:border-gray-700">
        <div className="flex items-center space-x-2">
          <h3 className="font-semibold text-lg">{t("ai_chat")}</h3>
          <button
            onClick={toggleSessionList}
            className="p-1.5 hover:bg-gray-200 dark:hover:bg-gray-700 rounded-full"
            title="聊天历史"
          >
            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-5 h-5">
              <path strokeLinecap="round" strokeLinejoin="round" d="M8.25 6.75h12M8.25 12h12m-12 5.25h12M3.75 6.75h.007v.008H3.75V6.75zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zM3.75 12h.007v.008H3.75V12zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm-.375 5.25h.007v.008H3.75v-.008zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" />
            </svg>
          </button>
          <button
            onClick={handleNewSession}
            className="p-1.5 hover:bg-gray-200 dark:hover:bg-gray-700 rounded-full"
            title="新建对话"
          >
            <PlusIcon className="w-5 h-5" />
          </button>
        </div>
        {onClose && (
          <button 
            onClick={onClose}
            className="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
            title="关闭"
          >
            ✕
          </button>
        )}
      </div>
      
      {/* 会话列表 */}
      {showSessionList && (
        <div className="border-b p-2 dark:border-gray-700 max-h-64 overflow-y-auto">
          <h4 className="text-sm font-medium mb-2">所有对话</h4>
          <ul className="space-y-1">
            {sessions.length === 0 ? (
              <li className="text-sm text-gray-500 dark:text-gray-400 p-2">暂无对话历史</li>
            ) : (
              sessions.map(session => (
                <li 
                  key={session.id} 
                  className={`flex justify-between items-center p-2 rounded text-sm ${
                    session.id === activeSessionId 
                      ? 'bg-blue-100 dark:bg-blue-900' 
                      : 'hover:bg-gray-100 dark:hover:bg-gray-800'
                  }`}
                >
                  {editingSessionId === session.id ? (
                    <div className="flex items-center flex-grow mr-2">
                      <input
                        type="text"
                        value={editSessionTitle}
                        onChange={(e) => setEditSessionTitle(e.target.value)}
                        className="w-full p-1 text-sm border rounded dark:bg-gray-700 dark:border-gray-600"
                        autoFocus
                        title="编辑会话标题"
                        aria-label="编辑会话标题"
                      />
                      <button 
                        onClick={() => saveSessionTitle(session.id)}
                        className="ml-1 p-1 text-green-600 hover:text-green-700 dark:text-green-400 dark:hover:text-green-300"
                        title="保存标题"
                      >
                        <CheckIcon className="w-4 h-4" />
                      </button>
                      <button 
                        onClick={cancelEditingSession}
                        className="p-1 text-red-600 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300"
                        title="取消编辑"
                      >
                        <XMarkIcon className="w-4 h-4" />
                      </button>
                    </div>
                  ) : (
                    <>
                      <button 
                        className="flex-grow text-left truncate"
                        onClick={() => setActiveSession(session.id)}
                        title={`切换到对话: ${session.title}`}
                      >
                        {session.title}
                      </button>
                      <div className="flex items-center">
                        <button 
                          onClick={() => startEditingSession(session.id, session.title)}
                          className="p-1 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
                          title="编辑标题"
                        >
                          <PencilIcon className="w-4 h-4" />
                        </button>
                        <button 
                          onClick={() => deleteSession(session.id)}
                          className="p-1 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
                          title="删除对话"
                        >
                          <TrashIcon className="w-4 h-4" />
                        </button>
                      </div>
                    </>
                  )}
                </li>
              ))
            )}
          </ul>
        </div>
      )}
      
      {/* 聊天消息区域 */}
      <div className="flex-1 overflow-y-auto p-4 space-y-4">
        {activeSession?.messages.slice(1).map((message, index) => (
          <div 
            key={index} 
            className={`flex ${message.role === 'user' ? 'justify-end' : 'justify-start'}`}
          >
            <div 
              className={`max-w-[80%] rounded-lg p-3 ${
                message.role === 'user' 
                  ? 'bg-blue-100 dark:bg-blue-900 dark:text-white' 
                  : 'bg-gray-100 dark:bg-gray-800 dark:text-white'
              }`}
            >
              {message.role === 'assistant' ? (
                <MarkdownViewer content={message.content} className="text-sm" />
              ) : (
                <p className="whitespace-pre-line text-sm">{message.content}</p>
              )}
            </div>
          </div>
        ))}
        
        {/* 流式内容显示 */}
        {streamingContent && (
          <div className="flex justify-start">
            <div className="max-w-[80%] rounded-lg p-3 bg-gray-100 dark:bg-gray-800 dark:text-white">
              <MarkdownViewer content={streamingContent} className="text-sm" />
            </div>
          </div>
        )}
        
        {/* 加载中指示器 */}
        {isLoading && !streamingContent && (
          <div className="flex justify-start">
            <div className="max-w-[80%] rounded-lg p-3 bg-gray-100 dark:bg-gray-800 dark:text-white">
              <div className="flex space-x-2">
                <div className="w-2 h-2 rounded-full bg-gray-400 animate-bounce" style={{ animationDelay: '0ms' }}></div>
                <div className="w-2 h-2 rounded-full bg-gray-400 animate-bounce" style={{ animationDelay: '150ms' }}></div>
                <div className="w-2 h-2 rounded-full bg-gray-400 animate-bounce" style={{ animationDelay: '300ms' }}></div>
              </div>
            </div>
          </div>
        )}
        
        {/* 错误消息 */}
        {error && (
          <div className="text-center text-red-500 dark:text-red-400">
            {error}
          </div>
        )}
        
        <div ref={messagesEndRef} />
      </div>
      
      {/* 剪贴板内容显示 */}
      {clipboardContent && (
        <div className="px-4 pb-2">
          <div className="bg-gray-100 dark:bg-gray-800 p-2 rounded-md text-xs overflow-hidden text-gray-700 dark:text-gray-300">
            <div className="flex justify-between items-center mb-1">
              <span className="font-medium">剪贴板内容</span>
              <button
                onClick={() => setClipboardContent('')}
                className="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
                title="清除剪贴板内容"
              >
                ✕
              </button>
            </div>
            <div className="max-h-20 overflow-y-auto">
              <pre className="whitespace-pre-wrap">{clipboardContent}</pre>
            </div>
          </div>
        </div>
      )}
      
      {/* 输入区域 */}
      <div className="border-t p-4 dark:border-gray-700">
        <div className="flex space-x-2">
          <Textarea
            value={input}
            onChange={handleInputChange}
            onKeyDown={handleKeyDown}
            placeholder={
              selectedCode 
                ? t("ask_about_code") 
                : selectedDocument 
                  ? t("ask_about_document") 
                  : t("ask_about_repo")
            }
            className="min-h-[60px] resize-none"
            disabled={isLoading || !activeSession}
            aria-label="聊天输入框"
          />
          <div className="flex flex-col justify-end space-y-2">
            <Button
              onClick={() => void readFromClipboard()}
              className="p-2 w-10 h-10 border-[2px] rounded-md border-black bg-blue-400 text-black shadow-[3px_3px_0_0_#000000] transition-transform hover:-translate-x-0.5 hover:-translate-y-0.5 hover:bg-blue-300 dark:border-gray-700 dark:bg-blue-600 dark:text-white dark:shadow-[3px_3px_0_0_#1f1f1f] dark:hover:bg-blue-500"
              disabled={isLoading || !activeSession}
              type="button"
              title="从剪贴板粘贴"
              aria-label="从剪贴板粘贴"
            >
              <ClipboardIcon className="h-5 w-5" />
            </Button>
            <Button
              onClick={() => void sendMessage()}
              className="p-2 w-10 h-10 border-[2px] rounded-md border-black bg-blue-400 text-black shadow-[3px_3px_0_0_#000000] transition-transform hover:-translate-x-0.5 hover:-translate-y-0.5 hover:bg-blue-300 dark:border-gray-700 dark:bg-blue-600 dark:text-white dark:shadow-[3px_3px_0_0_#1f1f1f] dark:hover:bg-blue-500"
              disabled={isLoading || (!input.trim() && !clipboardContent) || !activeSession}
              type="button"
              title="发送消息"
              aria-label="发送消息"
            >
              <PaperAirplaneIcon className="h-5 w-5" />
            </Button>
          </div>
        </div>
      </div>
    </div>
  );
} 